package analiseSintatica.Regras.Comandos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;

import java.util.LinkedList;

import analiseSemantica.ErroSemantico;
import analiseSemantica.Tipos.TipoSemantico;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.AnalisadorSintatico;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.Regras.Expressoes.RegraExpressao;

/**
 * Classe que reconhece o comando if
 * @author anderson
 * @author Elisson
 */
public class RegraIf extends Regra {

    protected static Regra instancia;


    protected String estrutura = "if '(' <expressao> ')' <comandos> [else <comandos>]";

    /**
     * Construtor privado necessario ao singleton
     */
    private RegraIf() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraIf getInstance() {
        if (instancia == null) {
            instancia = new RegraIf();
        }
        return (RegraIf) instancia;
    }
    

    public TiposSemanticos analisar(LinkedList<LinkToken> tokens) throws ErroSintaticoException {
        
    	tokens.removeFirst();
        reconheceLexema(tokens, "delimitador", "(", estrutura);
        
        TiposSemanticos tipoexpressao = RegraExpressao.getInstance().analisar(tokens);
        if(tipoexpressao != null){
	        TipoSemantico tipoexpr = tipoexpressao.removeTipos();
	        String tipoexp = (String)tipoexpr.getTipo();
	        if(!tipoexp.toLowerCase().equals("boolean")){
	        	AnalisadorSintatico.errosemanticos.add(new ErroSemantico("Expressao deve ter valor booleano", tipoexpr.getLinha()));
	        }
        }
        
        reconheceLexema(tokens, "delimitador", ")", estrutura);
        
        TiposSemanticos tipos = RegraBloco.getInstance().analisar(tokens);

        if (tokens.getFirst().getToken().equals("else")) {
        	tokens.removeFirst();
        	TiposSemanticos temp = RegraBloco.getInstance().analisar(tokens);
        	while(temp != null && temp.size() != 0){
        		tipos.addTipos(temp.removeTipos());
        	}
        }
        return tipos;
    }

    protected void setPrimeiro() {
    	this.primeiro.add("if");
    }
}
